package org.xxpay.pay.channel.alizftpay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayDomain;
import org.xxpay.pay.service.CommonService;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping("/api/auth")
public class GetAlipayUserIdController extends BaseApiService {

    private static final MyLog _log = MyLog.getLog(GetAlipayUserIdController.class);

    @Autowired
    private CommonService commonService;

    /**
     * 支付宝网关（固定）
     */
    public static final  String URL="https://openapi.alipay.com/gateway.do";

    /**
     * 授权url
     */
    public static final  String ALIPAY_URL = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";

    /**
     * 应用id
     *
     */
    public static final  String APP_ID="2019072465958567";

    /**
     * 应用私钥
     */
    public static final  String APP_PRIVATE_KEY="MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCQAg8VY68UgeLZzE9FDIBhv7Cp37ZRA/1JI8GnE3X8imrkCZ23bls0Odnp1QF9E+MOVj00/+slf69BqCJ8DkC5L2b0Y+pH/aGHaFB9shP2rcdaFHRv1L2JSFqzSvi1Fprn11oaqMDruiBJU+gVvLi1OB/v4JP6Xej8jTnx5//eyIiKTI4SDQP0gQ5Bz1E2YMT/tSdDsPvuSOA6Q7Ya9gqOAIv3zDL4BVx5U5YfrjlmrSWTCE7YeEwdJnV1bG1iC5iVZDsxoec/yEf0sAu3V4npNlftGgkfwA28vilDLX/VaIVkvYlsgCnHoVVlCtaYKx8DqwubmujwbhFFhxHgxO7fAgMBAAECggEAY5GY3kAjMLmxoMd705EWPv+r5XhxdUid2vEnFx8EiA0oZO0lKEvcMZsCSYPmWJXkeugzv65m5nGHOo1G8qFkLOZSeA2RUh9SjO4aIR58YSW8XVMhQqVEO2RUmfzvQz4S8tPaT+54HUR+yFSEdmsbBul8Y33Sstw1mFEJTHINXvocYATO4GL3hSCzi1Ghpnb2wVQZCxE3yXMRST+RC3FoCBXK0p4fYcU22HIz2c//3ZbiZGazejkZ2E5JkXVylq3hHSxgGNr/dNyARTsBFsloPlDADHfGetvW3CNSJOATY5kL4VGUpHLEVY5bj42oiLgaIkFrP4SbvdV5Z3f5EzKKwQKBgQDJtXtf+ukdh6KivzZXeWotNgX929pZukZxeyYoifLn02+6XzKPQQtYx5RShSy5kiM22R2JMYpGPK7wE1n9T6OsCDW1l84YP+QhajH423OHh5QGD2k2upwSI2gSlocLQdwXkQrSP5ZEDR9OYODj761gGeH66wG5H8SqmQ5zrfiSoQKBgQC2xMP9JCbyHR4wUyyDy/QsdIjN9019lZn0yAaTDsxCK+/j/peyMIqLY167w7+sx9zOdyfClyWurzIvLWl9+Y5wP7TCpLghJTw6GfTpOnB/X+H6MzQ1hmAUQQD+KOOgr0BvAuRnZyz0IKYN4Bh6ldJDteV8Rn/1uqfEWZV3pQeRfwKBgHG4nO9XEhjxAJOLBIM6087bl3MxgaB28gJG8ROH+ugS//nudB3qCRCrrQb9SGLzbmEc9ZcE1DWXPvXhoym6vcde9ZEFHk/zrZXdPoFUkIUHvj/QbnxJp3Zeee2I6mhBYGn0/0ncScbiMxVIb2JzHaeB0DNcTaNmssWP92Lm4a8hAoGAUbP6bUJpCpjLswyrfKuDFxBtS62+/WIQNeXpUnouA3LCxag9RhH/DTq50bQ7DlE2OzH3Gz0YQlPdWkuxufgCndlMxCqAiYisuMh7vHs8aSSCz6duMnNEpik8+WFsCJvvcPDZDASKiwPBV7iTGNG68jvxP7IAZ+guMU9eyuKCVJ8CgYBBgqPeEbFOeRtIim3SzVLYlc46YbDMV2/pA317/WRwa78Jljig4+dscyCo9LF05nizq876/iZ8+0yG2bE6dv8WKXIF5ZLrUlYxo9OexD4aLniH+2ASvFtiwkxbwZFgl+jFQ5rrsPc90Oox4tJOXLwaiW02D/6kJlY/IOC5vajxyA==";

    /**
     * 参数返回格式
     */
    public static final  String FORMAT="json";

    /**
     * 编码集
     */
    public static final  String CHARSET="UTF-8";

    /**
     * 支付宝公钥
     */
    public static final  String ALIPAY_PUBLIC_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+EvmgLqUQhPC2G8miZpiBE+B6dX+0xYIoGJGsdsGn8mtXNEpj+KyOfQz2MMLq8uJETCKn/IsSRqgc3r6b4FvbwXs5KUkpfYM2uFiQYWCFWrk6/OZzi28xAoKj63IXaiqiFBAz0m6Pc/vcdR97PQysgxWHF5zd6IkKkGvCHryz4w4a8PcGgBOI+vnJqAZqHe0XpcCFv8dKtx9Lof6O/ToBBJgNeEvpnfOIpd5PpEmMlWe1Udp7CUvrGJhbybm4iLEMIURpK0Qx5KYiUds/pz2TM/INOYX5rKAetCPui8mjWl3mC9A5ZmtPGZKs0wd6aFkevQo9qb8UMJ3T89eFtMEQIDAQAB";

    /**
     * 商户生成签名字符串所使用的签名算法类型
     */
    public static final  String SIGN_TYPE="RSA2";

    /**
     *  跳转到授权界面
     */
    @RequestMapping(value = "/alipay")
    public String authAlipay(HttpServletRequest request, ModelMap model) {
        String returnUrl = request.getParameter("returnUrl");
        Map<String,String> maps = new HashMap<>();
        // 页面回调地址 必须与应用中的设置一样
        String payUrl;
        PayDomain payDomain = commonService.payDomainService.getRandomPayDomain((byte)2, (byte)3);
        if(payDomain == null) {
            JSONObject json = new JSONObject();
            json.put("code", PayConstant.RETURN_VALUE_FAIL);
            json.put("message", "获取不到域名");
            model.put("errMsg", json);
            return "common/pc_error";
        }
        String domainUrl = payDomain.getDomainUrl();
        if(!domainUrl.endsWith("/")) domainUrl += "/";
        domainUrl += "api";
        payUrl = domainUrl;
        String notify_url = payUrl + "/auth/alipay/imf_" + payDomain.getId();
        _log.info("获取支付宝用户ID的URL:{}", notify_url);
        //回调地址必须经encode
        notify_url = java.net.URLEncoder.encode(notify_url);
        //重定向到授权页面
        return "redirect:"+ ALIPAY_URL + "?app_id=" + payDomain.getAppId() + "&scope=auth_base&redirect_uri=" + notify_url + "&returnUrl=" + returnUrl;
    }

    /**
     *  跳转到授权界面（指定域名ID,主要用于测试）
     */
    @RequestMapping(value = "/alipay/{payDomainId}")
    public String authAlipay2(HttpServletRequest request, ModelMap model, @PathVariable Integer payDomainId) {
        String returnUrl = request.getParameter("returnUrl");
        // 页面回调地址 必须与应用中的设置一样
        String payUrl;
        PayDomain payDomain = commonService.payDomainService.findById(payDomainId);
        if(payDomain == null) {
            JSONObject json = new JSONObject();
            json.put("code", PayConstant.RETURN_VALUE_FAIL);
            json.put("message", "获取不到域名");
            model.put("errMsg", json);
            return "common/pc_error";
        }
        String domainUrl = payDomain.getDomainUrl();
        if(!domainUrl.endsWith("/")) domainUrl += "/";
        domainUrl += "api";
        payUrl = domainUrl;
        String notify_url = payUrl + "/auth/alipay/imf_" + payDomain.getId();
        _log.info("获取支付宝用户ID的URL:{}", notify_url);
        //回调地址必须经encode
        notify_url = java.net.URLEncoder.encode(notify_url);
        //重定向到授权页面
        return "redirect:"+ ALIPAY_URL + "?app_id=" + payDomain.getAppId() + "&scope=auth_base&redirect_uri=" + notify_url + "&returnUrl=" + returnUrl;
    }

    /**
     *  测试支付宝是否可以打开该域名（检测是否风控）
     */
    @RequestMapping(value = "/alipay/open")
    @ResponseBody
    public String oepnAlipay() {
        return "正常打开";
    }

    /**
     * 获取用户信息
     * @param request
     */
    @RequestMapping(value = "/alipay/imf_{payDomainId}")
    public String returnImf(HttpServletRequest request, @PathVariable Integer payDomainId) {
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == (values.length-1)) ? valueStr + values[i]:valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        _log.debug("获取userId,param={}", params);
        PayDomain payDomain = commonService.payDomainService.findById(payDomainId);
        String appId = payDomain.getAppId();
        String appPrivateKey = payDomain.getAppPrivateKey();
        String alipayPublicKey = payDomain.getAlipayPublicKey();
        _log.debug("获取userId,payDomain={}", payDomain);
        String userId = buildRequest(params, appId, appPrivateKey, alipayPublicKey);
        _log.info("获取userId={}", userId);
        params.put("userId",userId);
        String returnUrl = params.get("returnUrl");
        if(StringUtils.isBlank(returnUrl) || "null".equals(returnUrl)) {
            request.setAttribute("userId", userId);
            return "common/utip";
        }
        returnUrl = URLDecoder.decode(returnUrl);
        //重定向到口令controller
        if(returnUrl.indexOf("?") != -1) {
            return "redirect:"+ returnUrl + "&userId=" + userId;
        }else {
            return "redirect:"+ returnUrl + "?userId=" + userId;
        }
    }

    public static  String buildRequest(Map sParaTemp, String appId, String appPrivateKey, String alipayPublicKey){
        AlipayClient alipayClient = new DefaultAlipayClient(URL, appId, appPrivateKey, FORMAT, CHARSET, alipayPublicKey, SIGN_TYPE);
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode((String)sParaTemp.get("auth_code"));
        request.setGrantType("authorization_code");
        try {
            AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
            _log.info("获取支付宝用户ID：{}", oauthTokenResponse.getUserId());
            return oauthTokenResponse.getUserId();
        } catch (AlipayApiException e) {
            //处理异常
            e.printStackTrace();
        }
        return null;
    }

}
